package com.sxkiler.demo.rpc.client;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.sxkiler.demo.rpc.nacos.NacosTemplate;
import com.sxkiler.demo.rpc.pojo.MessageContext;
import com.sxkiler.demo.rpc.pojo.Response;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

import java.util.concurrent.Callable;
/**
 * 实现Callable接口，重写call方法
 */
public class NettyClientHandler extends ChannelInboundHandlerAdapter implements Callable {

    private ChannelHandlerContext channelHandlerContext;

    private MessageContext messageContext;

    private NacosTemplate nacosTemplate;
    public NettyClientHandler() {
        super();
        //  nacosTemplate = new NacosTemplate();
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("调用ctx方法");
        this.channelHandlerContext = ctx;
    }
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println("来自服务端的消息："+msg);
        if (msg instanceof MessageContext){
            System.out.println("调用read0方法");
            channelRead0(ctx,(MessageContext) msg);
        }
    }

    protected synchronized void channelRead0(ChannelHandlerContext channelHandlerContext, MessageContext response) throws Exception {
        System.out.println("调用服务返回值："+response.toString());
        this.messageContext = response;
        //接收到服务端返回后，notify通知下面的call方法苏醒去做返回处理
        notify();
    }


    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        System.out.println("发生了异常");
        cause.printStackTrace();
        ctx.close();
    }

    @Override
    public synchronized Object call() throws Exception {//重写call方法
        System.out.println("调用call方法");
        channelHandlerContext.writeAndFlush(messageContext);
        //发送完数据后，wait等待服务端响应返回。
        wait();
        //拿到数据解析并转换成相应的返回类型
        Response response = JSON.parseObject(JSONObject.toJSONString(messageContext.getContext()), Response.class);
        return JSON.parseObject(JSONObject.toJSONString(response.getContext()), response.getContextType());
    }

    public MessageContext getMessageContext() {
        return messageContext;
    }

    public void setMessageContext(MessageContext messageContext) {
        this.messageContext = messageContext;
    }
}

